
package com.emser.unc.server;

import java.util.Date;

import javax.jdo.JDOCanRetryException;
import javax.jdo.JDOException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.emser.unc.serializable.UserAccountDTO;
import com.emser.unc.server.domain.UserAccount;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class LoginHelper extends RemoteServiceServlet {
  private static final long serialVersionUID = 2888983680310646846L;
  private static final int NUM_RETRIES = 5;
 
  public static String getApplitionURL(HttpServletRequest request) {
	  if ((request.getServerPort() == 80) || (request.getServerPort() == 443))
		 return request.getScheme() + "://" + request.getServerName() + request.getContextPath();
	  else
		 return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
		          + request.getContextPath();	  	  
  }

  public static UserAccountDTO getLoggedInUser(HttpSession session) {
	  PersistenceManager pm;
	  if (session == null)
		  return null; 
	  String userId = (String) session.getAttribute("userId");
	  if (userId == null)
		  return null; 
	  Key userName = KeyFactory.createKey(UserAccount.class.getSimpleName(), userId);
	  pm = PMF.get().getPersistenceManager();
	  Query q = pm.newQuery(UserAccount.class, "userName == :userName");
	  q.setUnique(true);
	  try {
		  UserAccount u = (UserAccount) q.execute(userName);
		  if(u == null)
			  return null;
		  else
			  return UserAccount.toDTO(u);
	  } finally {
		  q.closeAll();
		  pm.close(); 
	  }
  }

  public static void loginStarts(HttpSession session,UserAccountDTO userADTO) {
	  PersistenceManager pm = PMF.get().getPersistenceManager();
	  Transaction tx = null;
	  UserAccount oneResult = null, detached = null;
	  String userAName = userADTO.getName();
	  if(userAName != null){
		  Key keyUserName = KeyFactory.createKey(UserAccount.class.getSimpleName(), userAName);
		  Query q = pm.newQuery(UserAccount.class, "userName == :keyUserName");
		  q.setUnique(true);
		  try {
			  for (int i = 0; i < NUM_RETRIES; i++) {
				  tx = pm.currentTransaction();
				  tx.begin();
				  oneResult = (UserAccount) q.execute(keyUserName);
				  if (oneResult != null) {
					  oneResult.setLastLoginOn(new Date());	
					  detached = pm.detachCopy(oneResult);
				  } else {
					  oneResult = new UserAccount(userAName);
					  oneResult.setUserName(userAName);
					  oneResult.setLastLoginOn(new Date());	
					  pm.makePersistent(oneResult);
					  detached = pm.detachCopy(oneResult);
				  }
				  try {
					  tx.commit();
					  session.setAttribute("userId", detached.getUserName().getName());
					  session.setAttribute("loggedin", true);
					  break;
				  }
				  catch (JDOCanRetryException e1) {
					  if (i == (NUM_RETRIES - 1)) {
						  throw e1;
					  }
				  }
			  } 
		  }
		  catch (JDOException e) {
			  e.printStackTrace();
		  }
		  finally {
			  if (tx.isActive()) {
				  tx.rollback();
			  }
			  pm.close();
			  q.closeAll();
		  }
	  }
  }
  
  public static boolean isLoggedIn(HttpServletRequest req) {

	    if (req == null)
	      return false;
	    else {
	      HttpSession session = req.getSession();
	      if (session == null) {
	        return false;
	      } else {
	        Boolean isLoggedIn = (Boolean) session.getAttribute("loggedin");
	        if(isLoggedIn == null){
	          return false;
	        } else if (isLoggedIn){
	          return true;
	        } else {
	          return false;
	        }
	      }
	    }
	  }
  
}
